home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / misc / emu / ATUtilities.lha / ATUtilities / cdr.c < prev    next >
C/C++ Source or Header  |  2000-09-26  |  20KB  |  842 lines

  1. /* ******************************************************************* */
  2. /* **                                                               ** */
  3. /* **                  ATUtilities SCSI-CDROM-Player                ** */
  4. /* **            Copright (C) 1993-1994 by Thomas Dreibholz         ** */
  5. /* **                     All rights reserved                       ** */
  6. /* **                                                               ** */
  7. /* ******************************************************************* */
  8.  
  9. #include "ATUtilities.h"
  10. #include <devices/trackdisk.h>
  11. #include <devices/scsidisk.h>
  12.  
  13. UBYTE tc[100]=
  14. {
  15.  /* 00 */  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
  16.  /* 10 */  9,  9,  9,  9,  9,  9, 10, 11, 12, 13,
  17.  /* 20 */ 14, 15, 16, 17, 18, 19, 19, 19, 19, 19,
  18.  /* 30 */ 19, 19, 20, 21, 22, 23, 24, 25, 26, 27,
  19.  /* 40 */ 28, 29, 29, 29, 29, 29, 29, 29, 30, 31,
  20.  /* 50 */ 32, 33, 34, 35, 36, 37, 38, 39, 39, 39,
  21.  /* 60 */ 39, 39, 39, 39, 40, 41, 42, 43, 44, 45,
  22.  /* 70 */ 46, 47, 48, 49, 49, 49, 49, 49, 49, 49,
  23.  /* 80 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  24.  /* 90 */ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59
  25. };
  26.  
  27. UBYTE *CDPlayerPort="ATUtilities HiFi-Player";
  28. UBYTE *CDCatalogName="AT:HiFi-System/CDCatalog.dat";
  29.  
  30. struct CDCatalogEntry
  31. {
  32.  UWORD TitleCount;
  33.  UBYTE Name[60];
  34.  UWORD Address[100];
  35. };
  36.  
  37. struct CDCatalog
  38. {
  39.  UWORD                 EntryCount;
  40.  struct CDCatalogEntry Entry[256];
  41. };
  42.  
  43. #define LUN 0
  44. #define TOC_SIZE 804
  45.  
  46. struct TOCHeader
  47. {
  48.  WORD  Length;
  49.  UBYTE FirstTrack;
  50.  UBYTE LastTrack;
  51. };
  52.  
  53. struct TOCData
  54. {
  55.  UBYTE reserved1;
  56.  UBYTE Flags;
  57.  UBYTE TrackNumber;
  58.  UBYTE reserved2;
  59.  LONG  Address;
  60. };
  61.  
  62. struct DriveInfo
  63. {
  64.  UBYTE Peripheral_type;
  65.  UBYTE Modifier;
  66.  UBYTE Version;
  67.  UBYTE Flags1;
  68.  UBYTE Additional_length;
  69.  UBYTE reserved[2];
  70.  UBYTE Flags2;
  71.  UBYTE Vendor[8];
  72.  UBYTE Product[16];
  73.  UBYTE Revision[4];
  74. };
  75.  
  76. UBYTE startaudio[10]={ 0x48, 0, 0, 0, 0, 1, 0, 99, 99, 0 };
  77. UBYTE stopaudio[6]={ 0x1B, 0, 0, 0, 0, 0 };
  78. UBYTE eject[10]={ 0xc4, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  79. UBYTE readtoc[10]={ 0x43, 0, 0, 0, 0, 0, 0, TOC_SIZE>>8, TOC_SIZE & 0xFF };
  80. UBYTE driveinfo[6]={ 0x12, 0, 0, 0, 96, 0 };
  81. UBYTE test[10]={0xc6, 0x0a, 0, 0, 0, 0, 0, 0, 0, 0};
  82. UBYTE lock[6]={0x1e, 0, 0, 0, 1, 0};
  83. UBYTE unlock[6]={0x1e, 0, 0, 0, 0, 0 };
  84.  
  85. struct NewScreen HCScreenDef=
  86. {
  87.  0,256-102,640,102,3,
  88.  0,1,HIRES,CUSTOMSCREEN,
  89.  0,0,0,0
  90. };
  91.  
  92. UWORD Colors[]={0x97a,0x222,0xddd,0xff5,0xdff,0xe0e,0xf03,0x00f};
  93.  
  94. struct NewWindow HCWindowDef=
  95. {
  96.  0,0,640,102,0,1,
  97.  MENUPICK|GADGETUP,BORDERLESS,
  98.  0L,0L,0L,0L,0L,
  99.  50,50,640,100,
  100.  CUSTOMSCREEN
  101. };
  102.  
  103. struct TextAttr DigitalAttr=
  104. {
  105.  "hpcalc.font",
  106.  18,
  107.  FS_NORMAL,
  108.  FPF_DISKFONT
  109. };
  110.  
  111. UBYTE  Vendor[10];
  112. UBYTE  Product[18];
  113. UBYTE  Revision[6];
  114. UBYTE *CDName,*OldCDName=0xFFFFFFFF;
  115. UBYTE *OldIS=0xFFFFFFFF;
  116. BYTE   OldSymbol=-1;
  117.  
  118. BOOL GetDriveInfo();
  119. VOID OpenAll();
  120. VOID SaveList();
  121. VOID CloseAll();
  122. VOID PlaySymbol();
  123. VOID StopSymbol();
  124. VOID ShowCD();
  125. VOID ShowInfoString();
  126. VOID HiFiControl();
  127. VOID TimerTask();
  128. VOID CheckCD();
  129. VOID FindCD();
  130. VOID EdEntry();
  131. WORD SCSI();
  132.  
  133. struct Window    *HCWindow;
  134. struct Screen    *HCScreen;
  135. struct RastPort  *HCRPort;
  136. struct ViewPort  *HCViewPort;
  137. struct MenuStrip *MenuStrip;
  138. struct TextFont  *DigitalFont;
  139.  
  140. struct IOExtTD   *io;
  141. struct Task      *MainTask;
  142. struct Task      *SubTask;
  143. struct Message   *msg;
  144. struct SCSICmd   *scsi;
  145. struct Gadget    *LockGadget;
  146. struct MsgPort   *port,*stop,*reply;
  147. struct TOCHeader *tocheader;
  148. struct TOCData   *tocdata;
  149. struct Remember  *Remember;
  150. struct CDCatalog *catalog;
  151. LONG              dev=-1L;
  152. WORD              status=0;
  153. UBYTE             FirstTrack;
  154. UBYTE             LastTrack;
  155. UBYTE             CurrentTrack;
  156. UWORD             TrackAddress[100];
  157. UBYTE             TrackCount;
  158. UBYTE             cdpos=0;
  159.  
  160. ULONG                MClass;
  161. UWORD                MCode;
  162. struct Gadget       *MGad;
  163. struct IntuiMessage *IMsg;
  164.  
  165. struct MsgPort *UtilityPort;
  166. struct MsgPort *UserPort;
  167.  
  168. LONG IDCMPSignal,IDCMPSignalMask;
  169. LONG TimerSignal=-1L,TimerSignalMask;
  170. LONG PortSignal,PortSignalMask;
  171. LONG WaitSignalMask;
  172.  
  173. BOOL   play=FALSE,inserted=FALSE,elock=FALSE;
  174. UBYTE *buffer;
  175. UBYTE *sense;
  176.  
  177. struct Library *IntuitionBase;
  178. struct Library *GfxBase;
  179. struct Library *DiskfontBase;
  180. struct Library *ATUtilitiesBase;
  181.  
  182.  
  183. VOID main(argc,argv)
  184.  LONG   argc;
  185.  UBYTE *argv[];
  186. {
  187.  UBYTE          str[50];
  188.  REGISTER LONG  i,j,k;
  189.  REGISTER ULONG Signale;
  190.  REGISTER BOOL  bool;
  191.  
  192.  if(argc!=3)
  193.   {
  194.    printf("Aufruf: %s [SCSI-Device-Name] [CD-ROM-Unit]\n",argv[0]);
  195.    exit(0);
  196.   }
  197.  OpenAll(argv[1],atol(argv[2]));
  198.  
  199.  bool=FALSE;
  200.  while(bool==FALSE)
  201.   {
  202.    Signale=Wait(WaitSignalMask);
  203.    if(Signale & TimerSignalMask)
  204.     {
  205.      CheckCD();
  206.     }
  207.    if(Signale & PortSignalMask)
  208.     {
  209.      i=Received(UtilityPort);
  210.      while(i!=0)
  211.       {
  212.        switch(i)
  213.         {
  214.          case UTILITY_QUIT:
  215.            bool=TRUE;
  216.           break;
  217.          case 1012:
  218.            HiFiControl();
  219.           break;
  220.         }
  221.        i=Received(UtilityPort);
  222.       }
  223.     }
  224.    if((IDCMPSignalMask!=0) && (Signale & IDCMPSignalMask))
  225.     {
  226.      IMsg=GetMsg(UserPort);
  227.      while(IMsg!=NULL)
  228.       {
  229.        MClass=IMsg->Class;
  230.        MCode=IMsg->Code;
  231.        MGad=IMsg->IAddress;
  232.        ReplyMsg(IMsg);
  233.        switch(MClass)
  234.         {
  235.          case GADGETUP:
  236.            k=MGad->GadgetID;
  237.            if(k<=40)
  238.             {
  239.              if(inserted==TRUE)
  240.               {
  241.                if(k>LastTrack) k=LastTrack;
  242.                startaudio[4]=k;
  243.                if((SCSI(&startaudio,10,buffer,0L,SCSIF_WRITE))==0)
  244.                 {
  245.                  sprintf(&str,"Wiedergabe ab Track #%02ld",k);
  246.                  ShowInfoString(&str);
  247.                 }
  248.               }
  249.             }
  250.            else
  251.             {
  252.              switch(k)
  253.               {
  254.                case 10000:
  255.                  if(elock==FALSE) SCSI(&eject,10,buffer,0,SCSIF_WRITE);
  256.                 break;
  257.                case 10001:
  258.                  SCSI(&stopaudio,6,buffer,0,SCSIF_WRITE);
  259.                 break;
  260.                case 4096:
  261.                  if(LockGadget->Flags & SELECTED)
  262.                    { SCSI(&lock,6,buffer,0,SCSIF_WRITE); elock=TRUE; }
  263.                  else
  264.                    { SCSI(&unlock,6,buffer,0,SCSIF_WRITE); elock=FALSE; }
  265.                 break;
  266.                case 10005:
  267.                  if(CurrentTrack>FirstTrack) CurrentTrack--; else CurrentTrack=LastTrack;
  268.                  startaudio[4]=CurrentTrack;
  269.                  if((SCSI(&startaudio,10,buffer,0L,SCSIF_WRITE))==0)
  270.                   {
  271.                    sprintf(&str,"Wiedergabe ab Track #%02ld",CurrentTrack);
  272.                    ShowInfoString(&str);
  273.                   }
  274.                 break;
  275.                case 10006:
  276.                  if(CurrentTrack<LastTrack) CurrentTrack++; else CurrentTrack=FirstTrack;
  277.                  startaudio[4]=CurrentTrack;
  278.                  if((SCSI(&startaudio,10,buffer,0L,SCSIF_WRITE))==0)
  279.                   {
  280.                    sprintf(&str,"Wiedergabe ab Track #%02ld",CurrentTrack);
  281.                    ShowInfoString(&str);
  282.                   }
  283.                 break;
  284.               }
  285.             }
  286.           break;
  287.          case MENUPICK:
  288.            if((MENUNUM(MCode))==0)
  289.             {
  290.              switch(ITEMNUM(MCode))
  291.               {
  292.                case 0:
  293.                  SaveList();
  294.                 break;
  295.                case 2:
  296.                  EdEntry();
  297.                 break;
  298.               }
  299.             }
  300.           break;
  301.         }
  302.        IMsg=GetMsg(UserPort);
  303.       }
  304.     }
  305.   }
  306.  
  307.  CloseAll();
  308. }
  309.  
  310.  
  311. VOID OpenAll(name,num)
  312.  UBYTE *name;
  313.  UBYTE  num;
  314. {
  315.  register struct FileHandle *fh;
  316.  
  317.  CDName=NULL;
  318.  IntuitionBase=OpenLibrary("intuition.library",0L);
  319.  GfxBase=OpenLibrary("graphics.library",0L);
  320.  ATUtilitiesBase=OpenLibrary("at-utilities.library",0L);
  321.  if((IntuitionBase==NULL)||(GfxBase==NULL)) CloseAll();
  322.  if(ATUtilitiesBase==NULL)
  323.   {
  324.    puts("Keine ATUtilities-Library!");
  325.    CloseAll();
  326.   }
  327.  DiskfontBase=OpenLibrary("diskfont.library",0L);
  328.  if(DiskfontBase==NULL) CloseAll();
  329.  DigitalFont=OpenDiskFont(&DigitalAttr);
  330.  if(DigitalFont==NULL)
  331.   {
  332.    InfoRequest("Kann hpcalc/18-Font nicht laden!");
  333.    CloseAll();
  334.   }
  335.  UtilityPort=FindPort(CDPlayerPort);
  336.  if(UtilityPort!=NULL)
  337.   {
  338.    InfoRequest("ATUtilities CDROM-Player ist schon aktiv.");
  339.    CloseAll();
  340.   }
  341.  MainTask=FindTask(NULL);
  342.  port=CreatePort("scsi-communications.port",0);
  343.  stop=CreatePort("cd-diskchange.port",0);
  344.  reply=CreatePort("cd-diskchange-reply.port",0);
  345.  if((port==NULL)||(stop==NULL)||(reply==NULL))
  346.   {
  347.    InfoRequest("Kein Speicher für Ports!");
  348.    CloseAll();
  349.   }
  350.  io=CreateExtIO(port,sizeof(struct IOExtTD));
  351.  if(io==NULL)
  352.   {
  353.    InfoRequest("Kein Speicher für SCSI-Request!");
  354.    CloseAll();
  355.   }
  356.  dev=OpenDevice(name,num,io,0);
  357.  if(dev!=0)
  358.   {
  359.    puts("Device läßt sich nicht öffnen!");
  360.    CloseAll();
  361.   }
  362.  buffer=AllocRemember(&Remember,2048,MEMF_CLEAR|MEMF_PUBLIC);
  363.  scsi=AllocRemember(&Remember,sizeof(struct SCSICmd),MEMF_CLEAR|MEMF_PUBLIC);
  364.  sense=AllocRemember(&Remember,18,MEMF_CLEAR|MEMF_PUBLIC);
  365.  catalog=AllocRemember(&Remember,sizeof(struct CDCatalog),MEMF_CLEAR|MEMF_PUBLIC);
  366.  tocheader=AllocRemember(&Remember,sizeof(struct TOCHeader),MEMF_CLEAR|MEMF_PUBLIC);
  367.  tocdata=AllocRemember(&Remember,sizeof(struct TOCData),MEMF_CLEAR|MEMF_PUBLIC);
  368.  msg=AllocRemember(&Remember,sizeof(struct Message),MEMF_CLEAR|MEMF_PUBLIC);
  369.  if((msg==NULL)||(buffer==NULL)||(sense==NULL)||(catalog==NULL)||(tocheader==NULL)||(tocdata==NULL))
  370.   {
  371.    InfoRequest("Nicht genug Speicher!");
  372.    CloseAll();
  373.   }
  374.  TimerSignal=AllocSignal(-1L);
  375.  if(TimerSignal<0)
  376.   {
  377.    InfoRequest("Keine freien Task-Signale!");
  378.    CloseAll();
  379.   }
  380.  TimerSignalMask=(1L<<TimerSignal);
  381.  
  382.  SubTask=CreateProcess(TimerTask,500,"cd-diskchange.process",2);
  383.  if(SubTask==NULL)
  384.   {
  385.    InfoRequest("Kann Task nicht erstellen!");
  386.    CloseAll();
  387.   }
  388.  
  389.  fh=Open(CDCatalogName,MODE_OLDFILE);
  390.  if(fh!=NULL)
  391.   {
  392.    Read(fh,catalog,sizeof(struct CDCatalog));
  393.    Close(fh);
  394.   }
  395.  else
  396.   {
  397.    catalog->EntryCount=0;
  398.   }
  399.  
  400.  UtilityPort=CreatePort(CDPlayerPort,0);
  401.  if(UtilityPort==NULL)
  402.   {
  403.    ErrorRequest(ERROR_MPORT);
  404.    CloseAll();
  405.   }
  406.  
  407.  if((GetDriveInfo())==FALSE)
  408.   {
  409.    InfoRequest("Kann Laufwerksdaten nicht lesen!");
  410.    CloseAll();
  411.   }
  412.  
  413.  PortSignal=UtilityPort->mp_SigBit;
  414.  PortSignalMask=(1L<<PortSignal);
  415.  WaitSignalMask=PortSignalMask+TimerSignalMask;
  416. }
  417.  
  418.  
  419. VOID CloseAll()
  420. {
  421.  if(UtilityPort)
  422.   {
  423.    DeletePort(UtilityPort);
  424.    SCSI(&unlock,6,buffer,0,SCSIF_WRITE);
  425.   }
  426.  if(HCScreen!=NULL) HiFiControl();
  427.  if(SubTask)
  428.   {
  429.    msg->mn_Node.ln_Type=NT_MESSAGE;
  430.    msg->mn_ReplyPort=reply;
  431.    PutMsg(stop,msg);
  432.    WaitPort(reply);
  433.    Delay(20);
  434.   }
  435.  if(dev==0) CloseDevice(io);
  436.  if(io) DeleteExtIO(io);
  437.  if(port) DeletePort(port);
  438.  if(stop) DeletePort(stop);
  439.  if(reply) DeletePort(reply);
  440.  if(Remember) FreeRemember(&Remember,TRUE);
  441.  if(TimerSignal!=-1L) FreeSignal(TimerSignal);
  442.  if(DigitalFont) CloseFont(DigitalFont);
  443.  if(DiskfontBase) CloseLibrary(DiskfontBase);
  444.  if(ATUtilitiesBase) CloseLibrary(ATUtilitiesBase);
  445.  if(IntuitionBase) CloseLibrary(IntuitionBase);
  446.  if(GfxBase) CloseLibrary(GfxBase);
  447.  exit(0);
  448. }
  449.  
  450.  
  451. VOID TimerTask()
  452. {
  453.  register struct Message *msg;
  454.  
  455.  geta4();
  456.  msg=GetMsg(stop);
  457.  while(msg==NULL)
  458.   {
  459.    Signal(MainTask,TimerSignalMask);
  460.    if(play==TRUE)
  461.      Delay(45);
  462.    else
  463.      Delay(150);
  464.    msg=GetMsg(stop);
  465.   }
  466.  ReplyMsg(msg);
  467.  Exit(0);
  468. }
  469.  
  470.  
  471. /* Play-Symbol im Kontrolldisplay */
  472. VOID PlaySymbol()
  473. {
  474.  if((HCScreen!=NULL)&&(OldSymbol!=0))
  475.   {
  476.    DrawCPBorder(HCWindow,35,5,50,35);
  477.    SetAPen(HCRPort,3);
  478.    Move(HCRPort,40,12);
  479.    Draw(HCRPort,40,32);
  480.    Draw(HCRPort,80,22);
  481.    Draw(HCRPort,40,12);
  482.    OldSymbol=0;
  483.   }
  484. }
  485.  
  486. /* Stop-Symbol im Kontrolldisplay */
  487. VOID StopSymbol()
  488. {
  489.  if((HCScreen!=NULL)&&(OldSymbol!=2))
  490.   {
  491.    DrawCPBorder(HCWindow,35,5,50,35);
  492.    SetAPen(HCRPort,3);
  493.    Move(HCRPort,40,12);
  494.    Draw(HCRPort,40,32);
  495.    Draw(HCRPort,80,32);
  496.    Draw(HCRPort,80,12);
  497.    Draw(HCRPort,40,12);
  498.    OldSymbol=2;
  499.   }
  500. }
  501.  
  502. /* Titel im Kontrolldisplay */
  503. VOID ShowInfoString(tex)
  504.  UBYTE *tex;
  505. {
  506.  UBYTE str[50];
  507.  
  508.  if(HCScreen!=NULL)
  509.   {
  510.    if(tex==NULL)
  511.     {
  512.      if(OldIS!=NULL)
  513.       {
  514.        sprintf(&str,"%s %s, %s",&Vendor,&Product,&Revision);
  515.        DrawCPBorder(HCWindow,290,5,340,16);
  516.        SetAPen(HCRPort,3);
  517.        WriteMText(HCRPort,300,16,320,&str);
  518.        OldIS=NULL;
  519.       }
  520.     }
  521.    else
  522.     {
  523.      DrawCPBorder(HCWindow,290,5,340,16);
  524.      SetAPen(HCRPort,3);
  525.      WriteMText(HCRPort,300,16,320,tex);
  526.      OldIS=0xFFFFFFFF;
  527.     }
  528.   }
  529. }
  530.  
  531. /* Player im Kontrolldisplay */
  532. VOID ShowCD()
  533. {
  534.  if(CDName==OldCDName) return;
  535.  if(HCScreen!=NULL)
  536.   {
  537.    OldCDName=CDName;
  538.    DrawCPBorder(HCWindow,290,24,340,16);
  539.    SetAPen(HCRPort,3);
  540.    if(CDName==NULL)
  541.     {
  542.      WriteMText(HCRPort,300,35,320,"-- Keine CD eingelegt --");
  543.      SetFont(HCRPort,DigitalFont);
  544.      SetAPen(HCRPort,3);
  545.      WriteText(HCRPort,100,29,"-- --.--");
  546.      SetFont(HCRPort,GetOpalFont());
  547.     }
  548.    else if(CDName==1L)
  549.     {
  550.      WriteMText(HCRPort,300,35,320,"-- Eingelegte CD hat kein Audio-Format --");
  551.      SetFont(HCRPort,DigitalFont);
  552.      SetAPen(HCRPort,3);
  553.      WriteText(HCRPort,100,29,"00 --.--");
  554.      SetFont(HCRPort,GetOpalFont());
  555.     }
  556.    else
  557.      WriteMText(HCRPort,300,35,320,CDName);
  558.   }
  559. }
  560.  
  561. /* Kontrolldisplay */
  562. VOID HiFiControl()
  563. {
  564.  UBYTE          str[6];
  565.  REGISTER UWORD i,j;
  566.  
  567.  if(HCScreen==NULL)
  568.   {
  569.    HCScreen=OpenScreen(&HCScreenDef);
  570.    if(HCScreen!=NULL)
  571.     {
  572.      HCWindowDef.Screen=HCScreen;
  573.      HCWindow=OpenWindow(&HCWindowDef);
  574.      if(HCWindow!=NULL)
  575.       {
  576.        OldCDName=OldIS=0xFFFFFFFF;
  577.        OldSymbol=-1;
  578.        HCWindow->BlockPen=2;
  579.        HCRPort=HCWindow->RPort;
  580.        SetFont(HCRPort,GetOpalFont());
  581.        MenuStrip=BuildMenuStrip(HCWindow,7,AUTOBACKPEN);
  582.        if(MenuStrip!=NULL)
  583.         {
  584.          for(i=0;i<2;i++)
  585.           {
  586.            for(j=1;j<21;j++)
  587.             {
  588.              sprintf(&str,"%02ld",i*20+j);
  589.              CreateBoolGadget(HCWindow,35+((j-1)*30),50+(i*15),25,12,&str,i*20+j);
  590.             }
  591.           }
  592.          if(elock==FALSE)
  593.            LockGadget=CreateNToggleGadget(HCWindow,35,80,25,12,"L",4096);
  594.          else
  595.            LockGadget=CreateSToggleGadget(HCWindow,35,80,25,12,"L",4096);
  596.          CreateBoolGadget(HCWindow,65,80,115,12,"Auswurf",10000);
  597.          CreateBoolGadget(HCWindow,185,80,325,12,"Stop",10001);
  598.          CreateBoolGadget(HCWindow,515,80,55,12,"-",10005);
  599.          CreateBoolGadget(HCWindow,575,80,55,12,"+",10006);
  600.          AddMenu(MenuStrip,"CD-Liste",5,120);
  601.          AddItem(MenuStrip,"Eintrag ändern",300,'A',TRUE,TRUE);
  602.          AddItem(MenuStrip,GetOpalLine(),300,0,FALSE,FALSE);
  603.          AddItem(MenuStrip,"Liste sichern",300,'S',TRUE,TRUE);
  604.          UseMenuStrip(MenuStrip);
  605.          DrawPBorder(HCWindow,90,5,190,35);
  606.          UserPort=HCWindow->UserPort;
  607.          IDCMPSignal=UserPort->mp_SigBit;
  608.          IDCMPSignalMask=(1L<<IDCMPSignal);
  609.          WaitSignalMask=PortSignalMask+IDCMPSignalMask+TimerSignalMask;
  610.          HCViewPort=ViewPortAddress(HCWindow);
  611.          LoadRGB4(HCViewPort,&Colors,8);
  612.          ShowCD();
  613.          ShowInfoString(NULL);
  614.          if(play) PlaySymbol(); else StopSymbol();
  615.          return;
  616.         }
  617.       }
  618.     }
  619.   }
  620.  if(HCWindow)
  621.   {
  622.    ClearMenuStrip(HCWindow);
  623.    CloseWindow(HCWindow);
  624.   }
  625.  if(MenuStrip) RemoveMenuStrip(MenuStrip);
  626.  if(HCScreen) CloseScreen(HCScreen);
  627.  WaitSignalMask=PortSignalMask+TimerSignalMask;
  628.  IDCMPSignalMask=0;
  629.  HCScreen=NULL;
  630.  HCWindow=NULL;
  631.  MenuStrip=NULL;
  632. }
  633.  
  634. WORD SCSI(cmd,len,buf,buflen,direction)
  635.  UBYTE *cmd;
  636.  UBYTE *buf;
  637.  LONG   buflen;
  638.  WORD   len,direction;
  639. {
  640.  io->io_Command=HD_SCSICMD;
  641.  io->io_Data=scsi;
  642.  io->io_Length=sizeof(struct SCSICmd);
  643.  
  644.  scsi->scsi_Data=buf;
  645.  scsi->scsi_Length=buflen;
  646.  scsi->scsi_Flags=SCSIF_AUTOSENSE|direction;
  647.  scsi->scsi_SenseData=sense;
  648.  scsi->scsi_SenseLength=18;
  649.  scsi->scsi_SenseActual=0;
  650.  
  651.  scsi->scsi_Command=cmd;
  652.  scsi->scsi_CmdLength=len;
  653.  
  654.  cmd[1] |= LUN << 5;
  655.  
  656.  DoIO(io);
  657.  return(scsi->scsi_Status);
  658. }
  659.  
  660.  
  661. BOOL GetDriveInfo()
  662. {
  663.  struct DriveInfo *di;
  664.  
  665.  status=SCSI(&driveinfo,6,buffer,sizeof(struct DriveInfo),SCSIF_READ);
  666.  if(status==0)
  667.   {
  668.    di=buffer;
  669.    strncpy(&Vendor,di->Vendor,8);
  670.    Vendor[9]=0x00;
  671.    strncpy(&Product,di->Product,16);
  672.    Product[16]=0x00;
  673.    strncpy(&Revision,di->Revision,4);
  674.    Revision[4]=0x00;
  675.    return(TRUE);
  676.   }
  677.  return(FALSE);
  678. }
  679.  
  680. VOID CheckCD()
  681. {
  682.  REGISTER UWORD i,j,k;
  683.  UBYTE          str[50];
  684.  
  685.  if((SCSI(&test,10,buffer,512,SCSIF_READ))==0)
  686.   {
  687.    if(HCScreen!=NULL)
  688.     {
  689.      SetFont(HCRPort,DigitalFont);
  690.      SetAPen(HCRPort,3);
  691.      sprintf(&str,"%02d %02d.%02d",(UWORD)tc[buffer[2]],(UWORD)tc[buffer[4]],(UWORD)tc[buffer[5]]);
  692.      WriteText(HCRPort,100,29,&str);
  693.      SetFont(HCRPort,GetOpalFont());
  694.      CurrentTrack=tc[buffer[2]];
  695.     }
  696.    if(buffer[0]==0x00)
  697.     {
  698.      PlaySymbol();
  699.      play=TRUE;
  700.      inserted=TRUE;
  701.     }
  702.    else
  703.     {
  704.      StopSymbol();
  705.      inserted=FALSE;
  706.      play=FALSE;
  707.     }
  708.   }
  709.  
  710.  if((SCSI(&readtoc,10,buffer,TOC_SIZE,SCSIF_READ))==0)
  711.   {
  712.    inserted=TRUE;
  713.    CopyMem(buffer,tocheader,sizeof(struct TOCHeader));
  714.    CopyMem((ULONG)buffer+4L,tocdata,sizeof(struct TOCData));
  715.  
  716.    FirstTrack=tocheader->FirstTrack;
  717.    LastTrack=tocheader->LastTrack;
  718.  
  719.    j=0; k=0xFFFF;
  720.    for(i=0;i<tocheader->Length/8;i++)
  721.     {
  722.      if((tocdata->TrackNumber!=0xAA) && !(tocdata->Flags & 4))
  723.       {
  724.        TrackAddress[j]=tocdata->Address;
  725.        j++;
  726.        if(k==0xFFFF) k=tocdata->TrackNumber;
  727.       }
  728.     }
  729.    TrackCount=j;
  730.  
  731.    if(j!=0)
  732.     {
  733.      FindCD();
  734.      CDName=&catalog->Entry[cdpos].Name;
  735.      ShowCD();
  736.     }
  737.    else
  738.     {
  739.      ShowInfoString("Bitte legen Sie eine Audio-CD ein!");
  740.      CDName=1L;
  741.      ShowCD();
  742.     }
  743.   }
  744.  else
  745.   {
  746.    StopSymbol();
  747.    ShowInfoString(NULL);
  748.    CDName=NULL;
  749.    ShowCD();
  750.    inserted=FALSE;
  751.    play=FALSE;
  752.   }
  753. }
  754.  
  755. VOID FindCD()
  756. {
  757.  REGISTER UWORD i,j,k;
  758.  REGISTER BOOL  found;
  759.  
  760.  found=FALSE;
  761.  for(i=0;i<catalog->EntryCount;i++)
  762.   {
  763.    if(catalog->Entry[i].TitleCount==TrackCount)
  764.     {
  765.      k=0;
  766.      for(j=0;j<catalog->Entry[i].TitleCount;j++)
  767.       {
  768.        if(catalog->Entry[i].Address[j]==TrackAddress[j]) k++;
  769.       }
  770.      if(k==catalog->Entry[i].TitleCount)
  771.       {
  772.        cdpos=i;
  773.        found=TRUE;
  774.        goto cd_found;
  775.       }
  776.     }
  777.   }
  778.  
  779. cd_found:
  780.  if(found==FALSE)
  781.   {
  782.    cdpos=catalog->EntryCount;
  783.    catalog->Entry[cdpos].TitleCount=TrackCount;
  784.    strcpy(&catalog->Entry[cdpos].Name,"Unbekannte CD - Wählen Sie \"Eintrag ändern\" im Menü!");
  785.    for(i=0;i<TrackCount;i++)
  786.     {
  787.      catalog->Entry[cdpos].Address[i]=TrackAddress[i];
  788.     }
  789.    catalog->EntryCount++;
  790.   }
  791. }
  792.  
  793. VOID EdEntry()
  794. {
  795.  REGISTER BOOL           bool;
  796.  REGISTER UBYTE         *name;
  797.  register struct Window *win;
  798.  
  799.  if(inserted==FALSE) return;
  800.  win=CreateWindow(HCScreen,0L,
  801.                   88,2,544,40,
  802.                   GADGETUP|VANILLAKEY,
  803.                   BORDERLESS|ACTIVATE);
  804.  if(win!=NULL)
  805.   {
  806.    SetFont(win->RPort,GetOpalFont());
  807.    SetAPen(win->RPort,3);
  808.    WriteText(win->RPort,15,15,"Titel der aktuellen CD:");
  809.    CreateBoolGadget(win,492,24,50,12,"Okay",10);
  810.    name=CreateStringGadget(win,3,24,480,12,&catalog->Entry[cdpos].Name,58,20);
  811.    bool=FALSE;
  812.    while(bool==FALSE)
  813.     {
  814.      WaitPort(win->UserPort);
  815.      IMsg=GetMsg(win->UserPort);
  816.      if(IMsg->Class==GADGETUP) bool=TRUE;
  817.      if(IMsg->Code==13) bool=TRUE;
  818.      ReplyMsg(IMsg);
  819.     }
  820.    strcpy(&catalog->Entry[cdpos].Name,name);
  821.    CDName=name;
  822.    DeleteStdWindow(win);
  823.    ShowCD();
  824.   }
  825. }
  826.  
  827. VOID SaveList()
  828. {
  829.  register struct FileHandle *fh;
  830.  
  831.  if(catalog->EntryCount>0)
  832.   {
  833.    fh=Open(CDCatalogName,MODE_NEWFILE);
  834.    if(fh!=NULL)
  835.     {
  836.      Write(fh,catalog,catalog->EntryCount*sizeof(struct CDCatalogEntry));
  837.      Close(fh);
  838.     }
  839.   }
  840. }
  841.  
  842.